package com.lblin.dto;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.beanutils.PropertyUtils;

import com.xiaoleilu.hutool.util.BeanUtil;

public class BaseDTO implements Serializable, Cloneable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 速度快 = 6倍 new
	 * 
	 * @param transfrom
	 * @param transto
	 * @return
	 */
	@Deprecated
	public static <T> T ObjectTransferWithHutool(T transfrom, T transto) {

		BeanUtil.copyProperties(transfrom, transto);

		return transto;
	}

	/**
	 * 速度慢 = 12倍 new
	 * 
	 * @param transfrom
	 * @param transto
	 * @return
	 */
	@Deprecated
	public static <T> T ObjectTransferWithApache(T transfrom, T transto) {

		try {
			BeanUtils.copyProperties(transfrom, transto);
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}

		return transto;
	}

	/**
	 * 速度最快 = 5倍 new
	 * 
	 * @param transfrom
	 * @param transto
	 */
	public static <T> void ObjectTransferWithPropertyUtils(T transfrom, T transto) {

		try {
			PropertyUtils.copyProperties(transfrom, transto);
		} catch (IllegalAccessException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 只按照属性名匹配 ,无视set get方法和 class 是否匹配 。 速度 超快 = 1.2倍 new
	 * @param transfrom
	 * @param transto
	 * @param isJavaBean 是否是javabean转换为javabean
	 */
	public static <T> void ObjectTransferNotSafeButQuik(T transfrom, T transto, boolean isJavaBean) {

		try {
			if (isJavaBean) {
				transferOnlyJavaBean(transfrom, transto);
			} else {
				transferObj(transfrom, transto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 只按照属性名匹配 ,无视set get方法和 class 是否匹配 。 速度 超快 = 0.8倍 new
	 * 
	 * @param transfrom
	 * @param transto
	 */
	public static <T> void ObjectTransferNotSafeButQuik(T transfrom, T transto) {

		try {
			transferOnlyJavaBean(transfrom, transto);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	private static <T> void transferOnlyJavaBean(T transfrom, T transto)
			throws IllegalArgumentException, IllegalAccessException {
		Field[] fsf = transfrom.getClass().getFields();
		Field[] fst = transto.getClass().getFields();
		for (int i = 0; i < fsf.length; i++) {
			for (int j = 0; j < fst.length; j++) {
				if (fsf[i].getName().equals(fst[j].getName())) {
					fst[j].setAccessible(true);
					fsf[i].setAccessible(true);
					fst[j].set(transto, fsf[i].get(transfrom));
				}
			}
		}
	}

	private static <T> void transferObj(T transfrom, T transto)
			throws IllegalArgumentException, IllegalAccessException {
		if (transfrom instanceof Map) {// map

			if (transto instanceof Map) {
				transto = transfrom;
			} else if (transto instanceof DynaBean) {

				for (Object key : ((Map) transfrom).keySet()) {
					((DynaBean) transto).set(key.toString(), ((Map) transfrom).get(key));
				}

			} else {
				Field[] fst = transto.getClass().getFields();
				for (Object key : ((Map) transfrom).keySet()) {
					for (int j = 0; j < fst.length; j++) {
						if (fst[j].getName().equals(key.toString())) {
							fst[j].setAccessible(true);
							fst[j].set(transto, ((Map) transfrom).get(key));
						}
					}
				}
			}

		} else if (transfrom instanceof DynaBean) {// 动态bean
			final DynaProperty[] origDescriptors = ((DynaBean) transfrom).getDynaClass().getDynaProperties();
			if (transto instanceof Map) {
				for (DynaProperty origDescriptor : origDescriptors) {
					final String name = origDescriptor.getName();
					((Map) transto).put(name, ((DynaBean) transfrom).get(name));
				}

			} else if (transto instanceof DynaBean) {
				transto = transfrom;
			} else {
				Field[] fst = transto.getClass().getFields();
				for (DynaProperty origDescriptor : origDescriptors) {
					final String name = origDescriptor.getName();
					for (int i = 0; i < fst.length; i++) {
						if (fst[i].getName().equals(name)) {
							fst[i].setAccessible(true);
							fst[i].set(fst, ((DynaBean) transfrom).get(name));
						}
					}
				}
			}

		} else {// 按javabean处理
			Field[] fsf = transfrom.getClass().getFields();
			if (transto instanceof Map) {
				for (int i = 0; i < fsf.length; i++) {
					for (Object key : ((Map) transto).keySet()) {
						if (fsf[i].getName().equals(key.toString())) {
							fsf[i].setAccessible(true);
							((Map) transto).put(key, fsf[i].get(transfrom));
						}
					}
				}

			} else if (transto instanceof DynaBean) {
				for (int i = 0; i < fsf.length; i++) {
					fsf[i].setAccessible(true);
					((DynaBean) transto).set(fsf[i].getName(), fsf[i].get(transfrom));
				}
			} else {
				Field[] fst = transto.getClass().getFields();
				for (int i = 0; i < fsf.length; i++) {
					for (int j = 0; j < fst.length; j++) {
						if (fsf[i].getName().equals(fst[j].getName())) {
							fst[j].setAccessible(true);
							fsf[i].setAccessible(true);
							fst[j].set(transto, fsf[i].get(transfrom));
						}
					}
				}
			}
		}
	}

}
